package cn.dengl.sky.springboot.common.config.security;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    public  static final Logger logger=LogManager.getLogger(WebSecurityConfig.class);
    @Bean
    UserDetailsService customUserService(){
        logger.info("customUserService()");
        return new CustomUserService();
    }


    @Bean
    PasswordEncoder passwordEncoder(){
        return new CustomPasswordEncoder();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.customUserService())
               .passwordEncoder(this.passwordEncoder());
    }

    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
//    public LogoutSuccessHandler logoutSuccessHandler(){
//        return  new LogoutSuccessHandler() {
//            @Override
//            public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
//                try{
//                    SecurityUser user=(SecurityUser) authentication.getPrincipal();
//                    logger.info("USER : " + user.getUsername() + " LOGOUT SUCCESS !  ");
//                }catch (Exception e){
//                    logger.info("LOGOUT EXCEPTION , e : " + e.getMessage());
//                }
//                httpServletResponse.sendRedirect("/login");
//            }
//        };
//    }
    /**
     * 描述：csrf().disable()为了关闭跨域访问的限制，若不关闭则websocket无法与后台进行连接
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println("WebSecurityConfig configure()");
        http.headers().frameOptions().disable();
//        .antMatchers("/admin/**").hasRole("ADMIN")登录权限访问设置
//            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
//
//
//本文来自 陈振阳 的CSDN 博客 ，全文地址请点击：https://blog.csdn.net/xichenguan/article/details/73277337?utm_source=copy
//        http.authorizeRequests().antMatchers("/js/**","/css/**").permitAll();//定义不需要认证就可以访问
        http.csrf().disable().authorizeRequests()
                .anyRequest().authenticated()//配置了所有请求必须登陆后才能访问
                .and()
                .formLogin()
                .loginPage("/login1")
                .defaultSuccessUrl("/mymain.html")/*设置默认登录成功跳转页面*/
                .failureUrl("/login1?error=true")
                .permitAll()
                .and()
                .logout()
                //默认注销行为为logout，可以通过下面的方式来修改
//                .logoutUrl("/login1")
                //设置注销成功后跳转页面，默认是跳转到登录页面
                .logoutSuccessUrl("/login1").
                permitAll();
        /*session 失效后跳转*/
        http.sessionManagement().invalidSessionUrl("/login1");
//        只允许一个用户登录，，如果第二次登陆则第一个被踢下线重新登录
        http.sessionManagement().maximumSessions(1).expiredUrl("/login1");
    }
//    @Autowired
//    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//        logger.info("configureGlobal()");
//        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
//    }
    @Override
    public void configure(WebSecurity web) throws Exception {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/css/**","/js/**","/images/**");
    }

}
